#include "resultwidget.h"
#include "ui_resultwidget.h"
#include "sessionmanager.h"
#include <QMessageBox>
#include <QDateTime>
#include <QVBoxLayout>
#include <QDir>
#include <QSet>
#include <QScrollArea>
#include <QTimer>

int c=0;
QString arrC,deC;
QTime deT = QTime(3, 30),arrT;
QDate dd = QDate(2024, 3, 3);
MatrixGraph graph;
void loadAllFlights(const QString& folderPath);
QString dataPath = "C:\\Users\\LEO\\Desktop\\study\\QT\\allFlightsData";


//AccountManager accountManager;
//QSqlDatabase& db = AccountManager::getDatabase();

struct Flight {
    QString airline;     // 航空公司
    QString flightNumber; // 航班号
    QString departureCity; // 出发城市
    QString arrivalCity;   // 到达城市
    QTime departureTime;       // 出发时间
    QTime arrivalTime;         // 到达时间
    QDate date;
    double timeConsuming;
    double price;               // 票价
    bool isFull;             // 是否满座
};

ResultWidget::ResultWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ResultWidget),
    currentIndex(0) // 初始化当前索引
{
    ui->setupUi(this);
    loadAllFlights(dataPath);


    QSqlDatabase& db = AccountManager::getDatabase();  // 不要再次打开数据库

    // 确保数据库连接已经打开
    if (!db.isOpen()) {
        qDebug() << "Database is not open.";
    } else {
        qDebug() << "Database connection established.";
    }



    // Initialize journey scroll area and container
    journeyScrollArea = findChild<QScrollArea*>("journeyScrollArea");
    if (journeyScrollArea) {
        QWidget* journeyContainer = new QWidget();
        journeyResultLayout = new QVBoxLayout(journeyContainer);
        journeyContainer->setLayout(journeyResultLayout);
        journeyScrollArea->setWidget(journeyContainer);
        journeyScrollArea->setWidgetResizable(true);
    } else {
        qWarning() << "journeyScrollArea not found in the UI.";
        return; // Prevent further initialization if journeyScrollArea is not found
    }

    deEdit = findChild<QLineEdit*>("deEdit");
    arrEdit = findChild<QLineEdit*>("arrEdit");

    if (deEdit) {
        connect(deEdit, &QLineEdit::textChanged, this, &ResultWidget::on_deCChanged);
    }
    if (arrEdit) {
        connect(arrEdit, &QLineEdit::textChanged, this, &ResultWidget::on_arrCChanged);
    }
    travelDateEdit = new QDateEdit(this);
    travelDateEdit->setCalendarPopup(true);  // 启用日历弹出窗口
    travelDateEdit->setDate(QDate::currentDate());  // 默认选择当前日期

        // 将日期选择器添加到布局中
    ui->dateLayout->addWidget(travelDateEdit);
    // Connect the search button to the corresponding slot
    connect(ui->searchAllButton, &QPushButton::clicked, this, &ResultWidget::on_searchAllButton_clicked);
}

ResultWidget::~ResultWidget() {
    delete ui;
}

void ResultWidget::displayFlightResults(const QList<FlightJourney>& journeys) {
    // 清除旧的结果
    if (!journeyResultLayout) {
        qWarning() << "journeyResultLayout is not initialized.";
        return;
    }

    // 清空布局中的所有小部件
    QLayoutItem* item;
    while ((item = journeyResultLayout->takeAt(0)) != nullptr) {
        if (item->widget()) {
            item->widget()->deleteLater();
        }
        delete item;
    }

    // 限制航程数量为最多 5 个
    flightJourneys = journeys.mid(0, 30);
    currentIndex = 0;

    // 加载第一批航程
    loadNextBatch();
}

void ResultWidget::loadNextBatch() {
    // 调试日志，检查当前加载的航程信息
    qDebug() << "Loading batch of journeys from index" << currentIndex << "to" << qMin(currentIndex + 5, flightJourneys.size());
    const int batchSize = 15;  // 每次加载的航程数量设为 5
    int endIndex = qMin(currentIndex + batchSize, flightJourneys.size());

    for (int i = currentIndex; i < endIndex; ++i) {
        // 调试日志，检查每个航程的信息
        const FlightJourney& journey = flightJourneys[i];
        //qDebug() << "Journey" << i << ": Total Price =" << journey.totalPrice << ", Total Time =" << journey.totalTime << ", Number of Segments =" << journey.segments.size();

        FlightJourneyWidget* journeyWidget = new FlightJourneyWidget(this);
        journeyWidget->setTotalPrice(journey.getTotalPrice());
        journeyWidget->setTotalTime(journey.totalMinutes);
        journeyWidget->setTotalHours(journey.getTotalHours(journey.getTotalTime()));
        journeyWidget->setTotalMinutes(journey.getTotalMinutes(journey.getTotalTime()));
        journeyWidget->setSegmentCount(journey.segments.size());

        // 加载航段信息
        for (const FlightSegment& segment : journey.segments) {
            // 调试日志，检查每个航段的信息
            qDebug() << "  Segment: Flight Number =" << segment.flightNumber << ", Airline =" << segment.airline << ", Departure Airport =" << segment.departureAirport << ", Arrival Airport =" << segment.arrivalAirport << ", Departure Time =" << segment.departureTime.toString("HH:mm") << ", Arrival Time =" << segment.arrivalTime.toString("HH:mm") << ", Price =" << segment.price << ", Is Transfer =" << segment.isTransfer;
            FlightSegmentWidget* segmentWidget = new FlightSegmentWidget(journeyWidget);
            segmentWidget->setFlightNumber(segment.flightNumber);
            segmentWidget->setAirline(segment.airline);
            segmentWidget->setDepartureAirport(segment.departureAirport);
            segmentWidget->setArrivalAirport(segment.arrivalAirport);
            segmentWidget->setDepartureTime(segment.departureTime.toString("HH:mm"));
            segmentWidget->setArrivalTime(segment.arrivalTime.toString("HH:mm"));
            segmentWidget->setPrice(segment.price);
            segmentWidget->setIsTransfer(segment.isTransfer);

            journeyWidget->addSegmentWidget(segmentWidget);
        }

        QPushButton* bookButton = new QPushButton("购票", journeyWidget);
        connect(bookButton, &QPushButton::clicked, [this, i]() { on_bookJourneyButton_clicked(i); });
        journeyResultLayout->addWidget(bookButton);
        // 将航程添加到布局中
        journeyResultLayout->addWidget(journeyWidget);
        journeyWidget->show();

    }

    currentIndex = endIndex;

    // 如果还有剩余的航程未加载，则使用 QTimer 设置下一批次的加载
    if (currentIndex < flightJourneys.size()) {
        QTimer::singleShot(50, this, &ResultWidget::loadNextBatch);
    }

    journeyResultLayout->parentWidget()->update();
}


void ResultWidget::on_backMain_clicked()
{
    emit backMain();
}


void ResultWidget::on_searchAllButton_clicked()
{
    deC = deEdit->text();
    arrC = arrEdit->text();
    if (deC.isEmpty() || arrC.isEmpty()) {
           qWarning() << "Departure or arrival city is empty.";
           return;
       }
        else{qDebug() << "Calling findAllPaths()";}

       // Step 2: 调用 findAllPath() 函数查找所有路径
       QList<FlightJourney> journeys = graph.findAllPaths(deC, arrC, 2);
       qDebug() << "findAllPaths() returned";

       // Step 3: 显示查询结果
       if (journeys.isEmpty()) {
           qWarning() << "No journeys found from" << deC << "to" << arrC;
       } else {
            displayFlightResults(journeys);          
       }
}

void ResultWidget::on_bookJourneyButton_clicked(int journeyIndex) {
    if (journeyIndex >= 0 && journeyIndex < flightJourneys.size()) {
        const FlightJourney& journey = flightJourneys[journeyIndex];
        QDate selectedDate = travelDateEdit->date();

        // 获取当前登录用户ID
        QString userID = SessionManager::getUserID();

        if (userID.isEmpty()) {
            qWarning() << "User is not logged in.";
            return;
        }

        // 保存航程和航段信息到数据库
        if (saveJourneyToDatabase(userID, journey, selectedDate)) {
            saveFlightSegments(journey);
            qDebug() << "Journey and segments have been successfully saved!";
        } else {
            qWarning() << "Failed to save journey and segments.";
            return;
        }

        // 处理每个航段的预订
        for (const FlightSegment& segment : journey.segments) {
            bool success = bookFlight(userID);  // 调用保存预订信息的方法
            if (success) {
                qDebug() << "Booking successful for flight segment:" << segment.flightNumber;
            } else {
                qWarning() << "Booking failed for flight segment:" << segment.flightNumber;
            }
        }

        // 提示用户预订成功
        QMessageBox::information(this, "Booking Success", "Your flight has been successfully booked!");
    } else {
        qWarning() << "Invalid journey index for booking:" << journeyIndex;
    }
}


void ResultWidget::loadAllFlights(const QString& folderPath) {
    QDir directory(folderPath);
    QStringList files = directory.entryList(QStringList() << "*.txt", QDir::Files);
    QSet<QString> citySet;

    for (const QString& fileName : files) {
        QStringList cityNames = fileName.split("-");
        if (cityNames.size() < 2) {
            qDebug() << "文件名格式错误: " << fileName;
            continue;
        }
        QString fromCity = cityNames[0].trimmed();
        QString toCity = cityNames[1].replace(".txt", "").trimmed();

        if (!citySet.contains(fromCity)) {
            graph.addCity(fromCity);
            citySet.insert(fromCity);
        }
        if (!citySet.contains(toCity)) {
            graph.addCity(toCity);
            citySet.insert(toCity);
        }

        QString filePath = folderPath + "/" + fileName;
        QFile file(filePath);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug() << "无法打开文件: " << filePath;
            continue;
        }

        QTextStream in(&file);
        in.setCodec("GB18030");
        while (!in.atEnd()) {
            QString line = in.readLine().trimmed();
            QStringList parts = line.split("/");

            if (parts.size() < 8) {
                qDebug() << "文件格式错误: " << line;
                continue;
            }
            QString airline = parts[0].trimmed();
            QString flightNumber = parts[1].trimmed();
            QString deAirport = parts[2].trimmed();
            QString arrAirport = parts[3].trimmed();

            // 检查是否读取了空字符串作为城市名称
            if (deAirport.isEmpty() || arrAirport.isEmpty()) {
                qDebug() << "城市信息缺失: " << line;
                continue;
            }

            QTime deTime = QTime::fromString(parts[4].trimmed(), "HH:mm");
            QTime arrTime = QTime::fromString(parts[5].trimmed(), "HH:mm");
            double price = parts[6].trimmed().toDouble();
            double occupancy = parts[7].trimmed().remove("%").toDouble();

            if (!deTime.isValid() || !arrTime.isValid()) {
                //qDebug() << "时间格式错误: " << line;
                continue;
            }

            double timeC = deTime.secsTo(arrTime) / 3600.0;
            if (timeC < 0) {
                timeC += 24.0;
            }

            auto details = std::make_shared<FlightDetails>(airline, flightNumber, deAirport, arrAirport, deTime, arrTime, QDate::currentDate(), occupancy);
            graph.addEdge(fromCity, toCity, airline, flightNumber, deAirport, arrAirport, deTime, arrTime, price, occupancy, timeC, QDate::currentDate());

            /*qDebug() << "成功加载航班: " << airline << flightNumber << deAirport << "->" << arrAirport
                     << " 起飞时间: " << deTime.toString()
                     << " 降落时间: " << arrTime.toString()
                     << " 价格: " << price
                     << " 上座率: " << occupancy;*/
        }
    }
}


void ResultWidget::on_deCChanged(const QString& text) {
    qDebug() << "Departure city changed to:" << text;
    deC = text;
}

void ResultWidget::on_arrCChanged(const QString& text) {
    qDebug() << "Arrival city changed to:" << text;
    arrC = text;
}

bool ResultWidget::saveJourneyToDatabase(const QString& userID, const FlightJourney& journey, const QDate& travelDate) {
    QSqlDatabase& db = AccountManager::getDatabase();
    if (!db.isOpen() && !db.open()) {
        qDebug() << "Database connection failed during save journey: " << db.lastError().text();
        return false;
    }

    // 插入航程数据到 journeys 表
    QSqlQuery query(db);
    query.prepare("INSERT INTO journeys (start_city, end_city, total_price, total_time, user_id, travel_date, sort_choice) "
                  "VALUES (?, ?, ?, ?, ?, ?, ?)");
    query.addBindValue(journey.startCity);  // 起点城市
    query.addBindValue(journey.endCity);    // 终点城市
    query.addBindValue(journey.getTotalPrice());  // 总价格
    query.addBindValue(journey.getTotalTime());  // 总时间（以字符串存储）
    query.addBindValue(userID);  // 用户ID
    query.addBindValue(travelDate.toString("yyyy-MM-dd"));
    query.addBindValue(c);
    qDebug()<<c;
    qDebug()<<journey.getTotalTime();
    qDebug()<<journey.getTotalPrice();

    if (!query.exec()) {
        qDebug() << "Failed to save journey to database: " << query.lastError().text();
        return false;
    }

    // 获取最近插入的航程ID
    int journeyID = query.lastInsertId().toInt();  // 获取刚插入的journey的ID
    qDebug() << "Journey saved successfully with ID: " << journeyID;

    return true;
}

bool ResultWidget::saveFlightSegments(const FlightJourney& journey) {
    QSqlDatabase& db = AccountManager::getDatabase();
    if (!db.isOpen() && !db.open()) {
        qDebug() << "Database connection failed during saving flight segments: " << db.lastError().text();
        return false;
    }

    QSqlQuery query(db);
    query.prepare("SELECT last_insert_rowid()");  // 获取最近插入的行的ID（SQLite的特性）
    if (!query.exec() || !query.next()) {
        qDebug() << "Failed to get last inserted journey ID: " << query.lastError().text();
        return false;
    }

    int journeyID = query.value(0).toInt();  // 获取刚插入的journey的ID
    qDebug() << "Using Journey ID: " << journeyID;

    query.prepare("INSERT INTO flight_segments (journey_id, from_city, to_city, flight_number, airline, "
                  "departure_airport, arrival_airport, departure_time, arrival_time, price, is_transfer) "
                  "VALUES (:journeyID, :fromCity, :toCity, :flightNumber, :airline, "
                  ":departureAirport, :arrivalAirport, :departureTime, :arrivalTime, :price, :isTransfer)");

    for (const FlightSegment& segment : journey.segments) {
        // 使用命名参数绑定值
        query.bindValue(":journeyID", journeyID);  // journey_id INTEGER
        query.bindValue(":fromCity", segment.fromCity);  // from_city TEXT
        query.bindValue(":toCity", segment.toCity);  // to_city TEXT
        query.bindValue(":flightNumber", segment.flightNumber);  // flight_number TEXT
        query.bindValue(":airline", segment.airline);  // airline TEXT
        query.bindValue(":departureAirport", segment.departureAirport);  // departure_airport TEXT
        query.bindValue(":arrivalAirport", segment.arrivalAirport);  // arrival_airport TEXT
        query.bindValue(":departureTime", segment.departureTime.toString("HH:mm:ss"));  // departure_time TEXT
        query.bindValue(":arrivalTime", segment.arrivalTime.toString("HH:mm:ss"));  // arrival_time TEXT
        query.bindValue(":price", segment.price);  // price REAL
        query.bindValue(":isTransfer", segment.isTransfer ? "Yes" : "No");  // is_transfer TEXT

        // 执行插入
        if (!query.exec()) {
            qDebug() << "Failed to insert segment into flight_segments table:" << query.lastError().text();
            break;  // 如果插入失败，停止循环，进行调试
        }
    }

    qDebug() << "Flight segments saved successfully to database.";
    return true;
}

bool ResultWidget::bookFlight(const QString& userID) {
    QSqlDatabase& db = AccountManager::getDatabase();
    if (!db.isOpen() && !db.open()) {
        qDebug() << "Database connection failed during booking: " << db.lastError().text();
        return false;
    }

    // 获取当前时间作为预订时间
    QString bookingTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");

    // Step 1: 获取 journey_id
    QSqlQuery journeyQuery(db);
    journeyQuery.prepare("SELECT journey_id FROM journeys WHERE user_id = :userID ORDER BY journey_id DESC LIMIT 1");
    journeyQuery.bindValue(":userID", userID);

    if (!journeyQuery.exec() || !journeyQuery.next()) {
        qDebug() << "Failed to retrieve journey_id for userID: " << userID << ", error:" << journeyQuery.lastError().text();
        return false;
    }

    int journeyID = journeyQuery.value(0).toInt();
    if (journeyID <= 0) {
        qDebug() << "Invalid journey_id retrieved for userID: " << userID;
        return false;
    }
    qDebug() << "Successfully retrieved journey_id: " << journeyID;

    // Step 2: 插入 user_bookings
    QSqlQuery query(db);
    query.prepare("INSERT INTO user_bookings (user_id, journey_id, booking_time) "
                  "VALUES (?, ?, ?)");
    query.addBindValue(userID);      // 用户ID
    query.addBindValue(journeyID);   // 行程ID
    query.addBindValue(bookingTime); // 预订时间

    db.transaction();
    if (!query.exec()) {
        qDebug() << "Booking failed: " << query.lastError().text();
        db.rollback();
        return false;
    } else {
        qDebug() << "Booking inserted successfully.";
        db.commit();
        emit bookingCompleted();
        return true;
    }
}


void ResultWidget::on_preferBox_currentIndexChanged(int index)
{
    int criteria = index;
    deC = deEdit->text();
    arrC = arrEdit->text();
    if (deC.isEmpty() || arrC.isEmpty()) {
        qWarning() << "Departure or arrival city is empty.";
        return;
    }
    else{qDebug() << "Calling findAllPaths()";}

    // Step 2: 调用 findAllPath() 函数查找所有路径
    QList<FlightJourney> journeys = graph.findAllPaths(deC, arrC, 2);

    switch (criteria) {
            case 1: // 价格最低
                c = 1;
                std::sort(journeys.begin(), journeys.end(),
                          [](const FlightJourney& a, const FlightJourney& b) {
                              return a.totalPrice < b.totalPrice;
                          });
                break;
            case 2: // 总时间最短
                c = 2;
                std::sort(journeys.begin(), journeys.end(),
                          [](const FlightJourney& a, const FlightJourney& b) {
                              return a.totalMinutes < b.totalMinutes;
                          });
                break;
            case 3: // 转机次数最少
                std::sort(journeys.begin(), journeys.end(),
                          [](const FlightJourney& a, const FlightJourney& b) {
                              return a.segments.size() < b.segments.size();
                          });
                break;
            default:
                c = 0;
                qDebug() << "未知的排序规则";
                return;
        }

    // Step 3: 显示查询结果
    if (journeys.isEmpty()) {
        qWarning() << "No journeys found from" << deC << "to" << arrC;
    } else {
        displayFlightResults(journeys);
    }
}

void ResultWidget::on_forUButton_clicked()
{
    UserProfile up;
    up.analyzeJourneyData();
    QString startCity = up.getFrequentDepartureCity();
    QString endCity = up.getFrequentDestinationCity();
    QList<FlightJourney> journeys = graph.findAllPaths(startCity, endCity, 2);
    if(up.getPreferredSortOption()=="最短时间")
    {
        std::sort(journeys.begin(), journeys.end(),
                  [](const FlightJourney& a, const FlightJourney& b) {
            return a.totalMinutes < b.totalMinutes;
        });
    }
    else
        if(up.getPreferredSortOption()=="最少花费"){
            std::sort(journeys.begin(), journeys.end(),
                      [](const FlightJourney& a, const FlightJourney& b) {
                return a.totalPrice < b.totalPrice;
            });
        }
        else
            if(up.getPreferredSortOption()=="直飞优先"){
                std::sort(journeys.begin(), journeys.end(),
                          [](const FlightJourney& a, const FlightJourney& b) {
                    return a.segments.size() < b.segments.size();
                });
            }
            else{
                qDebug() << "无推荐航班";
            }


    if (journeys.isEmpty()) {
        qWarning() << "暂未找到推荐航班：" << startCity << "to" << endCity;
    } else {
        displayFlightResults(journeys);
    }

}
